package org.terramagnet.workflow.dynamic;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terramagnet.workflow.dynamic.definition.WorkflowDef;
import org.terramagnet.workflow.dynamic.factory.WorkFactory;

/**
 * 动态工作流门户服务.
 *
 * @author terrason
 */
public final class DynamicWorkflowService {

    private final Logger logger = LoggerFactory.getLogger(getClass());
    /**
     * 当前系统中的所有工作流引擎.
     */
    private Map<String, Workflow> workflows;
    /**
     * 当前系统中正在运行的工作流执行实例.
     */
    private final Map<Integer, WorkflowProcess> processes = new HashMap<Integer, WorkflowProcess>();
    /**
     * 用于生成工作流实例ID.
     */
    private final AtomicLong pid = new AtomicLong(0l);
    /**
     * 动态工作流系统全局异步工作线程池.
     */
    private final ExecutorService executor = Executors.newCachedThreadPool();

    /**
     * 工作任务原型.
     */
    @Resource
    private WorkFactory workFactory;
    /**
     * 工作流程定义.
     */
    private List<WorkflowDef> workflowDefinition;

    /**
     * 获取系统中的指定流程.
     *
     * @param name 流程名称
     * @return 工作流引擎或{@code null}
     */
    public Workflow getWorkflow(String name) {
        if (workflows == null) {
            try {
                loadWorkflows();
            } catch (IOException ex) {
                throw new IllegalStateException("无法加载动态工作流配置：" + ex.getMessage(), ex);
            }
        }
        return workflows.get(name);
    }

    /**
     * 加载所有的工作流引擎到系统内存中.
     */
    private synchronized void loadWorkflows() throws IOException {
        if (workflows != null) {
            return;
        }

        if (workFactory == null) {
            throw new IllegalStateException("尚未配置工作任务原型：workFactory==null");
        }

        if (workflowDefinition == null) {
            ObjectMapper jsonUtil = new ObjectMapper();
            jsonUtil.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

            InputStream workflowConfigStream = getClass().getResourceAsStream("/workflow.json");
            if(workflowConfigStream==null){
                throw new IllegalStateException("无法加载动态工作流配置：找不到/workflow.json配置文件");
            }
            try {
                workflowDefinition = jsonUtil.readValue(workflowConfigStream, new TypeReference<List<WorkflowDef>>() {
                });
            } finally {
                workflowConfigStream.close();
            }
        }
        
        for (WorkflowDef workflowDef : workflowDefinition) {
            //TODO
        }

    }

    /**
     * 工作任务原型.
     *
     * @param workFactory the workFactory to set
     */
    public void setWorkFactory(WorkFactory workFactory) {
        this.workFactory = workFactory;
    }

    /**
     * 工作流程定义.
     *
     * @param workflowDefinition the workflowDefinition to set
     */
    public void setWorkflowDefinition(List<WorkflowDef> workflowDefinition) {
        this.workflowDefinition = workflowDefinition;
    }

}
